﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO.Ports;
using System.Linq;
using System.Reflection.Emit;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace rodate_9._20_
{
    public partial class Form1 : Form
    {
        SerialPort sp = new SerialPort();
        byte[] StarArray = new byte[] { 0XAE,0xA7,0XC1,0x05,0x01,0X01,0x05+0XC1+0X01+0X01,0xBC,0xB7 };//开始数组
        byte[] StopArray = new byte[] { 0XAE,0xA7,0XC2,0x05,0x01,0X02,0x05+0XC2+0X01+0X02,0xBC,0xB7 };//停止数组
        byte[] RecordArray = new byte[] { 0XAE,0xA7,0XB1,0x05,0x01,0X03,0x05+0XB1+0X01+0X03,0xBC,0xB7 };//计数数组 
        int count = 0;//计数
        int STA = 0;//状态位
        public Form1()
        {
            InitializeComponent();
            Control.CheckForIllegalCrossThreadCalls = false;//允许跨线程更新ui(易出错)
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            //设置初始值
            Port_cbox.Text = "COM1";//串口初始值
            Baud_cbox.Text = "9600";//波特率初始值

            Port_cbox.Items.AddRange(System.IO.Ports.SerialPort.GetPortNames());//获取电脑可用串口

            sp.DataReceived += new SerialDataReceivedEventHandler(Port_DataReceived);//订阅串口数据接收处理事件

            this.toolStripStatusLabel3.Text = DateTime.Now.ToString();//显示系统时间
            Time_tmr.Start();//开启时间定时器
        }
        /// <summary>
        /// 配置串口信息
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Port_op_btn_Click(object sender, EventArgs e)
        {
            try
            {
                if (sp.IsOpen)//判断串口是否打开 true:已经打开 flase: 关闭
                {
                    Star_btn.Enabled = false;//开始按钮失能
                    Stop_btn.Enabled = false;//停止按钮失能          
                    sp.Close();//关闭串口
                    Star_tmr.Stop();//停止定时器
                    Port_op_btn.Text = "打开串口";
                    this.toolStripStatusLabel1.Text = "阻塞";
                    this.toolStripStatusLabel1.BackColor = System.Drawing.Color.Red;
                    Port_cbox.Enabled = true;
                    Baud_cbox.Enabled = true;
                }
                else
                {
                    Star_btn.Enabled = true;//开始按钮使能                   
                    Port_cbox.Enabled = false;
                    Baud_cbox.Enabled = false;
                    this.toolStripStatusLabel1.Text = "就绪";
                    this.toolStripStatusLabel1.BackColor= System.Drawing.Color.Green;
                    sp.PortName = Port_cbox.Text;//串口
                    sp.BaudRate = Convert.ToInt32(Baud_cbox.Text);//波特率
                    sp.DataBits = Convert.ToInt32("8");
                    //校验位
                    sp.Parity = System.IO.Ports.Parity.None;
                    //停止位
                    sp.StopBits = System.IO.Ports.StopBits.One;
                    sp.Open();
                    STA = 0;
                    count = 0;
                    Count_Nudown.Value=count;
                    Port_op_btn.Text = "关闭串口";
                }
            }
            catch (Exception ex)
            {
                //捕获可能发生的异常并进行处理

                //捕获到异常，创建一个新的对象，之前的不可以再用
                sp = new System.IO.Ports.SerialPort();
                //刷新COM选项
                Port_cbox.Items.Clear();
                Port_cbox.Items.AddRange(System.IO.Ports.SerialPort.GetPortNames());
                Port_op_btn.Text = "打开串口";
                Port_op_btn.BackColor = Color.ForestGreen;
                MessageBox.Show(ex.Message);
                Port_cbox.Enabled = true;
                Baud_cbox.Enabled = true;
            }
        }
        /// <summary>
        /// 串口接收事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Port_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            if (sp.BytesToRead > 8)
            {
                int bytes = sp.BytesToRead;
                byte[] data = new byte[bytes];
                sp.Read(data, 0, bytes);
                //String strReadData = "";
                //foreach (byte da in data)
                //    strReadData += $"{da.ToString("X")},";
                //Console.WriteLine($"data:{strReadData}");
                switch (STA)
                {
                    case 0:Star_DataProcess(data, bytes);break;
                    case 1:Record_DataProcess(data, bytes);break;
                    case 2:Stop_DataProcess(data, bytes);break;
                    default:break;
                }
            }
        }
        /// <summary>
        /// 开始数据应答处理
        /// </summary>
        /// <param name="Array"></param>
        /// <param name="ArrayLen"></param>
        public void Star_DataProcess(byte[] Array,int ArrayLen)
        {
            int i,j=0;
            for(i = 0; i < ArrayLen; i++)
            {
                if(Array[i] == 0xAE)//找到帧头
                {
                    for(j = 0; j < StarArray.Length; j++)
                    {
                        if (Array[i+j] != StarArray[j])
                        {
                            //Console.WriteLine("Array[{0}]:{2},StarArray[{1}]:{3}", i,j, Array[i], StarArray[j]);
                            break;
                                }
                    }
                }
                if (j == 9)
                {
                    Stop_btn.Enabled = true;//停止按钮使能
                    STA = 1;
                    Star_tmr.Stop();
                    j = 0;
                }
            }           
        }
        /// <summary>
        /// 停止数据应答处理
        /// </summary>
        /// <param name="Array"></param>
        /// <param name="ArrayLen"></param>
        public void Stop_DataProcess(byte[] Array, int ArrayLen)
        {
            int i, j = 0;
            for (i = 0; i < ArrayLen; i++)
            {
                if (Array[i] == 0xAE)//找到帧头
                {
                    for (j = 0; j < StopArray.Length; j++)
                    {
                        if (Array[i+j] != StopArray[j])
                        {
                            //Console.WriteLine("Array[{0}]:{2},StarArray[{1}]:{3}", i,j, Array[i], StarArray[j]);
                            break;
                        }
                    }
                }
                if (j == 9)
                {
                    STA = 0;
                    Star_btn.Enabled = true;//开始按钮使能
                    Stop_btn.Enabled = false;
                    j = 0;
                }
            }           
        }
        /// <summary>
        /// 记录数据处理
        /// </summary>
        /// <param name="Array"></param>
        /// <param name="ArrayLen"></param>
        public void Record_DataProcess(byte[] Array, int ArrayLen)
        {
            int i, j = 0;
            for (i = 0; i < ArrayLen; i++)
            {
                if (Array[i] == 0xAE)//找到帧头
                {
                    for (j = 0; j < RecordArray.Length; j++)
                    {
                        if (Array[i+j] != RecordArray[j])
                        {
                            //Console.WriteLine("Array[{0}]:{2},StarArray[{1}]:{3}", i, j, Array[i], StarArray[j]);
                            break;
                        }
                    }
                }
                if (j == 9)
                {
                    count++;
                    Count_Nudown.Value = count;
                    j = 0;
                }
            }         
        }
        /// <summary>
        /// 自动发送开始数据帧
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Star_tmr_Tick(object sender, EventArgs e)
        {
            sp.Write(StarArray, 0, StarArray.Length);//自动发送开始数据帧      
        }
        /// <summary>
        /// 开始按钮事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Star_btn_Click(object sender, EventArgs e)
        {
            //Console.WriteLine($"STA:{STA.ToString()}");
            if (STA == 0)
            {                                           
                Star_btn.Enabled = false;              
                Star_tmr.Start();//定时器启动（自动发送开始命令）
            }
            
        }
        /// <summary>
        /// 停止按钮事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Stop_btn_Click(object sender, EventArgs e)
        {
            Stop_btn.Enabled=false;
            STA = 2;
            sp.Write(StopArray,0, StopArray.Length);
            Star_tmr.Stop();
            
        }
        /// <summary>
        /// 系统时间事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Time_tmr_Tick(object sender, EventArgs e)
        {
            this.toolStripStatusLabel3.Text = DateTime.Now.ToString();
        }
    }
}
